package com.mto.module.karaoke.service.persistence;

import java.util.List;

import com.liferay.portal.kernel.bean.BeanReference;
import com.liferay.portal.kernel.cache.CacheRegistryUtil;
import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
import com.liferay.portal.kernel.dao.orm.FinderPath;
import com.liferay.portal.kernel.dao.orm.Query;
import com.liferay.portal.kernel.dao.orm.QueryPos;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.dao.orm.Session;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.service.persistence.ResourcePersistence;
import com.liferay.portal.service.persistence.UserPersistence;
import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;
import com.mto.module.karaoke.model.Song;
import com.mto.module.karaoke.model.impl.SongImpl;
import com.mto.module.karaoke.model.impl.SongModelImpl;

public class SongFinderImpl extends BasePersistenceImpl<Song> implements SongFinder {
	
	private static final String FINDER_CLASS_NAME_ENTITY = SongImpl.class.getName();
	private static final String FINDER_CLASS_NAME_LIST_WITH_PAGINATION = FINDER_CLASS_NAME_ENTITY+".List1";
	private static final String FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION = FINDER_CLASS_NAME_ENTITY+ ".List2";
	private static final FinderPath FINDER_PATH_WITH_PAGINATION_FIND_BY_N_A_C_S_RN = new FinderPath(
		SongModelImpl.ENTITY_CACHE_ENABLED,
		SongModelImpl.FINDER_CACHE_ENABLED, 
		SongImpl.class,
		FINDER_CLASS_NAME_LIST_WITH_PAGINATION, 
		"findByN_A_C_S_RN",
		new String[] { 
			String.class.getName(), 
			String.class.getName(),
			String.class.getName(), 
			String.class.getName(),
			Long.class.getName(),
			"java.lang.Integer",
			"java.lang.Integer",
			"com.liferay.portal.kernel.util.OrderByComparator"
		}
	);
	private static final FinderPath FINDER_PATH_WITHOUT_PAGINATION_FIND_BY_N_A_C_S_RN = new FinderPath(
		SongModelImpl.ENTITY_CACHE_ENABLED,
		SongModelImpl.FINDER_CACHE_ENABLED, SongImpl.class,
		FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION, "findByN_A_C_S_RN",
		new String[] { 
			String.class.getName(), 
			String.class.getName(),
			String.class.getName(), 
			String.class.getName(),
			Long.class.getName()
		},
		SongModelImpl.SONGNAME_COLUMN_BITMASK|
		SongModelImpl.SONGAUTHOR_COLUMN_BITMASK|
		SongModelImpl.SONGCATEGORY_COLUMN_BITMASK|
		SongModelImpl.SONGSINGER_COLUMN_BITMASK|
		SongModelImpl.RECORDNUMBER_COLUMN_BITMASK
	);
	private static final FinderPath FINDER_PATH_COUNT_BY_N_A_C_S_RN = new FinderPath(
		SongModelImpl.ENTITY_CACHE_ENABLED,
		SongModelImpl.FINDER_CACHE_ENABLED, 
		Long.class,
		FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION, 
		"countByN_A_C_S_RN",
		new String[] { 
			String.class.getName(), 
			String.class.getName(),
			String.class.getName(), 
			String.class.getName(),
			Long.class.getName()
		}
	);
	
	/**
	 * Caches the song in the entity cache if it is enabled.
	 * @param song  the song
	 */
	public void cacheResult(Song song) {
		EntityCacheUtil.putResult(SongModelImpl.ENTITY_CACHE_ENABLED,
				SongImpl.class, song.getPrimaryKey(), song);

		song.resetOriginalValues();
	}

	/**
	 * Caches the songs in the entity cache if it is enabled.
	 * @param songs  the songs
	 */
	public void cacheResult(List<Song> songs) {
		for (Song song : songs) {
			if (EntityCacheUtil.getResult(SongModelImpl.ENTITY_CACHE_ENABLED, SongImpl.class, song.getPrimaryKey()) == null) {
				cacheResult(song);
			} else {
				song.resetOriginalValues();
			}
		}
	}

	/**
	 * Clears the cache for all songs.
	 * <p>
	 * The {@link com.liferay.portal.kernel.dao.orm.EntityCache} and
	 * {@link com.liferay.portal.kernel.dao.orm.FinderCache} are both cleared by
	 * this method.
	 * </p>
	 */
	@Override
	public void clearCache() {
		if (_HIBERNATE_CACHE_USE_SECOND_LEVEL_CACHE) {
			CacheRegistryUtil.clear(SongImpl.class.getName());
		}
		EntityCacheUtil.clearCache(SongImpl.class.getName());
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_ENTITY);
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST_WITH_PAGINATION);
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION);
	}

	/**
	 * Clears the cache for the song.
	 * <p>
	 * The {@link com.liferay.portal.kernel.dao.orm.EntityCache} and
	 * {@link com.liferay.portal.kernel.dao.orm.FinderCache} are both cleared by
	 * this method.
	 * </p>
	 */
	@Override
	public void clearCache(Song song) {
		EntityCacheUtil.removeResult(SongModelImpl.ENTITY_CACHE_ENABLED, SongImpl.class, song.getPrimaryKey());
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST_WITH_PAGINATION);
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION);
	}

	@Override
	public void clearCache(List<Song> songs) {
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST_WITH_PAGINATION);
		FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION);
		for (Song song : songs) {
			EntityCacheUtil.removeResult(SongModelImpl.ENTITY_CACHE_ENABLED, SongImpl.class, song.getPrimaryKey());
		}
	}

	/**
	 * Returns all the songs where songName = &#63; and songAuthor = &#63; and
	 * songCategory = &#63; and songSinger = &#63; and recordNumber = &#63;.
	 * 
	 * @param songName  the song name
	 * @param songAuthor  the song author
	 * @param songCategory the song category
	 * @param songSinger  the song singer
	 * @param recordNumber  the record number
	 * @return the matching songs
	 * @throws SystemException if a system exception occurred
	 */
	public List<Song> search(String songName, String songAuthor, Integer songCategory, String songSinger, long recordNumber) throws SystemException {
		return search(songName, songAuthor, songCategory, songSinger, recordNumber, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
	}

	/**
	 * Returns a range of all the songs where songName = &#63; and songAuthor =
	 * &#63; and songCategory = &#63; and songSinger = &#63; and recordNumber =
	 * &#63;.
	 * 
	 * <p>
	 * Useful when paginating results. Returns a maximum of
	 * <code>end - start</code> instances. <code>start</code> and
	 * <code>end</code> are not primary keys, they are indexes in the result
	 * set. Thus, <code>0</code> refers to the first result in the set. Setting
	 * both <code>start</code> and <code>end</code> to
	 * {@link com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return
	 * the full result set.
	 * </p>
	 * 
	 * @param songName  the song name
	 * @param songAuthor the song author
	 * @param songCategory  the song category
	 * @param songSinger  the song singer
	 * @param recordNumber  the record number
	 * @param start the lower bound of the range of songs
	 * @param end the upper bound of the range of songs (not inclusive)
	 * @return the range of matching songs
	 * @throws SystemException if a system exception occurred
	 */
	public List<Song> search(String songName, String songAuthor, Integer songCategory, String songSinger, long recordNumber, int start, int end) throws SystemException {
		return search(songName, songAuthor, songCategory, songSinger, recordNumber, start, end, null);
	}

	/**
	 * Returns an ordered range of all the songs where songName = &#63; and
	 * songAuthor = &#63; and songCategory = &#63; and songSinger = &#63; and
	 * recordNumber = &#63;.
	 * 
	 * <p>
	 * Useful when paginating results. Returns a maximum of
	 * <code>end - start</code> instances. <code>start</code> and
	 * <code>end</code> are not primary keys, they are indexes in the result
	 * set. Thus, <code>0</code> refers to the first result in the set. Setting
	 * both <code>start</code> and <code>end</code> to
	 * {@link com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return
	 * the full result set.
	 * </p>
	 * 
	 * @param songName the song name
	 * @param songAuthor the song author
	 * @param songCategory the song category
	 * @param songSinger  the song singer
	 * @param recordNumber the record number
	 * @param start the lower bound of the range of songs
	 * @param end  the upper bound of the range of songs (not inclusive)
	 * @param orderByComparator the comparator to order the results by (optionally  <code>null</code>) 
	 * @return the ordered range of matching songs
	 * @throws SystemException if a system exception occurred
	 */
	public List<Song> search(String songName, String songAuthor, Integer songCategory, String songSinger, long recordNumber, int start, int end, OrderByComparator orderByComparator) throws SystemException {
		
		FinderPath finderPath = null;
		Object[] finderArgs = null;

		if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS) && (orderByComparator == null)) {
			finderPath = FINDER_PATH_WITHOUT_PAGINATION_FIND_BY_N_A_C_S_RN;
			finderArgs = new Object[] { songName, songAuthor, songCategory, songSinger, recordNumber };
		} else {
			finderPath = FINDER_PATH_WITH_PAGINATION_FIND_BY_N_A_C_S_RN;
			finderArgs = new Object[] { songName, songAuthor, songCategory, songSinger, recordNumber, start, end, orderByComparator };
		}

		List<Song> list = (List<Song>) FinderCacheUtil.getResult(finderPath, finderArgs, this);

		if (list == null) {
			StringBundler query = null;
			if (orderByComparator != null) {
				query = new StringBundler(7 + (orderByComparator.getOrderByFields().length * 3));
			} else {
				query = new StringBundler(6);
			}
			query.append(_SQL_SELECT_SONG_WHERE);
			if (songName != null) {
				if (songName.equals(StringPool.BLANK)) {
					query.append(WHERE_SONGNAME_3);
				} else {
					query.append(WHERE_SONGNAME_2);
					if(songName.startsWith(StringPool.PERCENT)||songName.endsWith(StringPool.PERCENT)) {
						query.append(LIKE);
					} else {
						query.append(EQUAL);
					}
				}
			}
			if (songAuthor != null) {
				if (songAuthor.equals(StringPool.BLANK)) {
					query.append(WHERE_SONGAUTHOR_3);
				} else {
					query.append(WHERE_SONGAUTHOR_2);
					if(songAuthor.startsWith(StringPool.PERCENT)||songAuthor.endsWith(StringPool.PERCENT)) {
						query.append(LIKE);
					} else {
						query.append(EQUAL);
					}
				}
			}
			if (songCategory != null && songCategory > 0) {
				query.append(WHERE_SONGCATEGORY_2);
			}
			if (songSinger != null) {
				if (songSinger.equals(StringPool.BLANK)) {
					query.append(WHERE_SONGSINGER_3);
				} else {
					query.append(WHERE_SONGSINGER_2);
					if(songSinger.startsWith(StringPool.PERCENT)||songSinger.endsWith(StringPool.PERCENT)) {
						query.append(LIKE);
					} else {
						query.append(EQUAL);
					}
				}
			}
			if(recordNumber >= 0) {
				query.append(WHERE_RECORDNUMBER_2);
			}
			if (orderByComparator != null) {
				appendOrderByComparator(query, _ORDER_BY_ENTITY_ALIAS,
						orderByComparator);
			}
			String sql = query.toString();
			Session session = null;
			try {
				session = openSession();
				Query q = session.createQuery(sql);
				QueryPos qPos = QueryPos.getInstance(q);
				if (songName != null) {
					qPos.add(songName);
				}
				if (songAuthor != null) {
					qPos.add(songAuthor);
				}
				if (songCategory != null && songCategory > 0) {
					qPos.add(songCategory);
				}
				if (songSinger != null) {
					qPos.add(songSinger);
				}
				if(recordNumber >= 0) {
					qPos.add(recordNumber);
				}
				list = (List<Song>) QueryUtil.list(q, getDialect(), start, end);
			} catch (Exception e) {
				throw processException(e);
			} finally {
				if (list == null) {
					FinderCacheUtil.removeResult(finderPath, finderArgs);
				} else {
					cacheResult(list);
					FinderCacheUtil.putResult(finderPath, finderArgs, list);
				}
				closeSession(session);
			}
		}
		return list;
	}

	/**
	 * Returns the number of songs where songName = &#63; and songAuthor = &#63;
	 * and songCategory = &#63; and songSinger = &#63; and recordNumber = &#63;.
	 * 
	 * @param songName the song name
	 * @param songAuthor the song author
	 * @param songCategory  the song category
	 * @param songSinger the song singer
	 * @param recordNumber the record number
	 * @return the number of matching songs
	 * @throws SystemException if a system exception occurred
	 */
	public int searchCount(String songName, String songAuthor, Integer songCategory, String songSinger, long recordNumber) throws SystemException {
		
		Object[] finderArgs = new Object[] { songName, songAuthor, songCategory, songSinger, recordNumber };
		Long count = (Long) FinderCacheUtil.getResult(FINDER_PATH_COUNT_BY_N_A_C_S_RN, finderArgs, this);

		if (count == null) {
			StringBundler query = new StringBundler(6);
			query.append(_SQL_COUNT_SONG_WHERE);
			if (songName != null) {
				if (songName.equals(StringPool.BLANK)) {
					query.append(WHERE_SONGNAME_3);
				} else {
					query.append(WHERE_SONGNAME_2);
					if(songName.startsWith(StringPool.PERCENT)||songName.endsWith(StringPool.PERCENT)) {
						query.append(LIKE);
					} else {
						query.append(EQUAL);
					}
				}
			}
			if (songAuthor != null) {
				if (songAuthor.equals(StringPool.BLANK)) {
					query.append(WHERE_SONGAUTHOR_3);
				} else {
					query.append(WHERE_SONGAUTHOR_2);
					if(songAuthor.startsWith(StringPool.PERCENT)||songAuthor.endsWith(StringPool.PERCENT)) {
						query.append(LIKE);
					} else {
						query.append(EQUAL);
					}
				}
			}
			if (songCategory != null && songCategory > 0) {
				query.append(WHERE_SONGCATEGORY_2);
			}
			if (songSinger != null) {
				if (songSinger.equals(StringPool.BLANK)) {
					query.append(WHERE_SONGSINGER_3);
				} else {
					query.append(WHERE_SONGSINGER_2);
					if(songSinger.startsWith(StringPool.PERCENT)||songSinger.endsWith(StringPool.PERCENT)) {
						query.append(LIKE);
					} else {
						query.append(EQUAL);
					}
				}
			}
			if(recordNumber >= 0) {
				query.append(WHERE_RECORDNUMBER_2);
			}
			String sql = query.toString();
			Session session = null;
			try {
				session = openSession();
				Query q = session.createQuery(sql);
				QueryPos qPos = QueryPos.getInstance(q);
				if (songName != null) {
					qPos.add(songName);
				}
				if (songAuthor != null) {
					qPos.add(songAuthor);
				}
				if (songCategory != null && songCategory > 0) {
					qPos.add(songCategory);
				}
				if (songSinger != null) {
					qPos.add(songSinger);
				}
				if(recordNumber >=0 ) {
					qPos.add(recordNumber);
				}
				count = (Long) q.uniqueResult();
			} catch (Exception e) {
				throw processException(e);
			} finally {
				if (count == null) {
					count = Long.valueOf(0);
				}
				FinderCacheUtil.putResult(FINDER_PATH_COUNT_BY_N_A_C_S_RN, finderArgs, count);
				closeSession(session);
			}
		}
		return count.intValue();
	}

	public void destroy() {
		EntityCacheUtil.removeCache(SongImpl.class.getName());
		FinderCacheUtil.removeCache(FINDER_CLASS_NAME_ENTITY);
		FinderCacheUtil.removeCache(FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION);
	}

	@BeanReference(type = SongPersistence.class)
	protected SongPersistence songPersistence;
	@BeanReference(type = UserSongsPersistence.class)
	protected UserSongsPersistence userSongsPersistence;
	@BeanReference(type = ResourcePersistence.class)
	protected ResourcePersistence resourcePersistence;
	@BeanReference(type = UserPersistence.class)
	protected UserPersistence userPersistence;
	
	private static final String EQUAL = " = ?";
	private static final String LIKE = " LIKE ?";
	private static final String _SQL_SELECT_SONG_WHERE = "SELECT song FROM Song song WHERE 1=1";
	private static final String _SQL_COUNT_SONG_WHERE = "SELECT COUNT(song) FROM Song song WHERE 1=1";
	private static final String WHERE_SONGNAME_2 = " AND song.songName";
	private static final String WHERE_SONGNAME_3 = " AND (song.songName IS NULL OR song.songName = ?)";
	private static final String WHERE_SONGAUTHOR_2 = " AND song.songAuthor";
	private static final String WHERE_SONGAUTHOR_3 = " AND (song.songAuthor IS NULL OR song.songAuthor = ?)";
	private static final String WHERE_SONGCATEGORY_2 = " AND song.songCategory=?";
	private static final String WHERE_SONGSINGER_2 = " AND song.songSinger";
	private static final String WHERE_SONGSINGER_3 = " AND(song.songSinger IS NULL OR song.songSinger = ?)";
	private static final String WHERE_RECORDNUMBER_2 = " AND song.recordNumber = ?";
	private static final String _ORDER_BY_ENTITY_ALIAS = "song.";
	private static final boolean _HIBERNATE_CACHE_USE_SECOND_LEVEL_CACHE = GetterUtil.getBoolean(PropsUtil.get(PropsKeys.HIBERNATE_CACHE_USE_SECOND_LEVEL_CACHE));
}
